﻿using System;
using System.IO;

namespace RVNetworkLib
{
    public class Packet
    {
        public const int HEADER_SIZE = 18;

        public uint MagicNumber { get; set; }
        public uint CheckSum { get; set; }
        public PacketType Type { get; set; }
        public uint UserID { get; set; }
        public uint DataLength { get; set; }
        public byte[] Payload { get; set; }

        public Packet()
        {
            MagicNumber = 0;
            CheckSum = 0;
            Type = PacketType.INVALID;
            UserID = 0;
            DataLength = 0;
            Payload = null;
        }

        public byte[] Serialize()
        {
            using (MemoryStream ms = new MemoryStream())
            {
                using (BinaryWriter writer = new BinaryWriter(ms))
                {
                    writer.Write(MagicNumber);
                    writer.Write(CheckSum);
                    writer.Write((ushort)Type);
                    writer.Write(UserID);
                    writer.Write(DataLength);

                    if (Payload != null)
                    {
                        writer.Write(Payload);
                    }
                }
                return ms.ToArray();
            }
        }

        static public Packet Deserialize(byte[] data)
        {
            Packet p = new Packet();
            using (MemoryStream ms = new MemoryStream(data))
            {
                using (BinaryReader reader = new BinaryReader(ms))
                {
                    p.MagicNumber = reader.ReadUInt32();
                    p.CheckSum = reader.ReadUInt32();
                    p.Type = (PacketType)reader.ReadUInt16();
                    p.UserID = reader.ReadUInt32();
                    p.DataLength = reader.ReadUInt32();
                    p.Payload = reader.ReadBytes((int)p.DataLength);
                }
            }
            return p;
        }

        static public Packet DeserializeHeader(byte[] data)
        {
            if (data.Length < Packet.HEADER_SIZE) return null;

            Packet p = new Packet();
            using (MemoryStream ms = new MemoryStream(data))
            {
                using (BinaryReader reader = new BinaryReader(ms))
                {
                    p.MagicNumber = reader.ReadUInt32();
                    p.CheckSum = reader.ReadUInt32();
                    p.Type = (PacketType)reader.ReadUInt16();
                    p.UserID = reader.ReadUInt32();
                    p.DataLength = reader.ReadUInt32();
                    p.Payload = null;
                }
            }
            return p;
        }
    }
}
